unit StockDataBlockPool;

interface

uses DataBlockAnalyze, StockDataPO, Contnrs, SyncObjs, ComCtrls;

type
  TStockDataBolocPool = class
  private
    FStockBlockInfos: TObjectList;
    ProgressBar: TProgressBar;
    SumCount, useCount: Integer;
  public
    procedure setProgressBar(AProgressBar: TProgressBar);
    function getNextBlockInfo(): TStockBolckInfo;
    function getPoolCount(): integer;
    procedure putBlockInfo(AStockBolckInfo: TStockBolckInfo);
    constructor Create(AStockBolckInfos: TObjectList); overload;
    constructor Create(ASumCount: Integer); overload;
    destructor Destroy();override;
    function HasNext(): Boolean;
  end;

implementation

var
  BlockPoolCS: TCriticalSection;

{ TStockDataBolocPool }

constructor TStockDataBolocPool.Create(AStockBolckInfos: TObjectList);
begin
  FStockBlockInfos := AStockBolckInfos;
  BlockPoolCS := TCriticalSection.Create;
  SumCount := AStockBolckInfos.Count;
  useCount := 0;
end;

constructor TStockDataBolocPool.Create(ASumCount: Integer);
begin
  FStockBlockInfos := TObjectList.Create(false);
  BlockPoolCS := TCriticalSection.Create;
  SumCount := ASumCount;
  useCount := 0;
end;

destructor TStockDataBolocPool.Destroy;
begin
  FStockBlockInfos.Free;
  BlockPoolCS.Free;
  inherited;
end;

function TStockDataBolocPool.getNextBlockInfo: TStockBolckInfo;
begin
  BlockPoolCS.Enter;
  try
    if FStockBlockInfos.Count > 0 then
    begin
      Randomize;
      Result := FStockBlockInfos.Items[Random(FStockBlockInfos.Count - 1)] as TStockBolckInfo;
      //Result := StockInfos.First as TStockInfo;

      FStockBlockInfos.Remove(Result);
      useCount := useCount + 1;
      if Assigned(ProgressBar) then
        ProgressBar.Position :=  useCount;
    end
    else
      Result := nil;
  finally
    BlockPoolCS.Leave;
  end;
end;

function TStockDataBolocPool.getPoolCount: integer;
begin
  BlockPoolCS.Enter;
  try
    Result := FStockBlockInfos.Count;
  finally
    BlockPoolCS.Leave;
  end;
end;

function TStockDataBolocPool.HasNext: Boolean;
begin
  BlockPoolCS.Enter;
  try
    Result := (SumCount > useCount);
  finally
    BlockPoolCS.Leave;
  end;
end;

procedure TStockDataBolocPool.putBlockInfo(AStockBolckInfo: TStockBolckInfo);
begin
  BlockPoolCS.Enter;
  try
    FStockBlockInfos.Add(AStockBolckInfo);
  finally
    BlockPoolCS.Leave;
  end;
end;

procedure TStockDataBolocPool.setProgressBar(AProgressBar: TProgressBar);
begin
  ProgressBar := AProgressBar;
  ProgressBar.Min := 0;
  ProgressBar.Max := SumCount - 1;
  ProgressBar.Position := 0;
end;

end.
